#pragma once

#include <iostream>
#include <mutex>
#include <unistd.h>

#include "acl/acl.h"
#include "atlas_model.h"
#include "dimp/preprocess_for_init.hpp"
#include "thread_safe_queue.h"
#include "dimp/dimp_init.hpp"
#include "dimp/dimp_tracking.hpp"
#include "dimp/dimp_optimizer.hpp"
#include "target_sender.h"
// #include "target_storage.h"


using namespace std;

struct STATE {
    Vector translation_vec;
    float score;
    int state;
};

struct UPDATE_INFO {
    Vector new_pos;
    Vector target_size;
    Vector sample_pos;
    float sample_scales;
    Nodes classifier_feat;
    void* origin_weight;
    int object_state;
    bool need_update;
    int frame_num;
};

class Tracker{
    public:
    Tracker(const char* modelpath[], string filepath);
    ~Tracker();

    AtlasError InitForAll();
    AtlasError LoadAllModel(int32_t& deviceId, aclrtContext& context, aclrtStream& stream, aclrtRunMode& runMode);
    AtlasError InitFirstFrame(cv::Mat img);
    AtlasError Tracking(cv::Mat img, Target_Box& result);
    AtlasError Update(aclrtContext context);

    private:
    AtlasError InitResource();
    void DestroyResource();
    struct STATE localize(Nodes scores, Vector sample_pos, float sample_scales, Vector target_size);
    

    private:
     /**用于初始化设备**/
    int32_t deviceId_;
    aclrtContext context_;
    aclrtStream stream_;    // 跟踪stream
    aclrtStream stream1_;   // 模型更新stream
    aclrtStream stream2_;   // 模型更新stream
    aclrtRunMode runMode_;
    aclrtEvent update_done_;
    bool isInited_;

    /*****每帧裁剪图像时使用**/
    string line_;
    string filepath_;
    char tempfilename_[10];
    Vector target_pos_;      //对应self.pos
	Vector target_size_;        //对应self.target_sz
	string image_full_path_;
	Mat sample_image_;
	Vector new_sample_size_;
	int new_target_area_;
	Box sample_coords_;
    float target_scale_;
    Vector sample_pos_;

    /*用于第一帧裁剪图像使用*/
    vector<cv::Mat> transform_imgs_;
    vector<Target_Box> transform_boxes_;
    Vector init_base_target_size_;
    Vector init_target_size_;   //对应self.target_sz
    Vector init_sample_pos_;
    Vector init_target_pos_;    //对应self.pos
    float init_target_scale_;
    float sample_scales_;
    Vector image_size_;


    Preprocess_for_init Image_pre_; //声明的图像预处理对象
    Dimp_Init Dimp_init_;           //Dimp模型初始化对象
    Dimp_Track Dimp_tracking_;     //Dimp跟踪对象
    Optimizer DiMPSteepestDescendGN_; //初始化分类模板



    void* total_classifier_feats_;  //第一帧计算出的分类特征
    uint32_t size_of_total_classifier_feats_;
    void* modulation1_;
    uint32_t size_of_modulation1_;  //调制向量1
    void* modulation2_;
    uint32_t size_of_modulation2_;  //调制向量2
    void* init_weights_;
    uint32_t size_of_init_weights_;
    void* origin_weight_;

    struct timeval begin_;
    struct timeval end_;
    struct timeval begin_1_;
    struct timeval end_1_;
    float time_cost_;

    Target_Box init_iou_box_;
    Target_Box iou_box_;
    Vector new_target_pos_;
    Vector new_pos_;
    int index_;
    int frame_nums_;
    int train_nums_;
    int count_;
    int update_wait_time_;
    bool update_begin_;
    STATE now_state_;

    ThreadSafeQueue<UPDATE_INFO> Update_InfoQueue_;
    TargetSender sender_;
    // TargetStorage storage_;
    float average_image_pre_time_ = 0.0;
    float average_scoremodel_time_ = 0.0;
    float average_ioumodel_time_ = 0.0;
};